package com.icongyou.enterprise.talent_analysis.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.icongyou.enterprise.common.exception.BusinessException;
import com.icongyou.enterprise.talent_analysis.entity.PortraitTemplate;
import com.icongyou.enterprise.talent_analysis.entity.dto.PortraitTemplateCreateRequest;
import com.icongyou.enterprise.talent_analysis.entity.dto.PortraitTemplateDTO;
import com.icongyou.enterprise.talent_analysis.entity.template.TemplateDimension;
import com.icongyou.enterprise.talent_analysis.entity.template.TemplateMetricMapping;
import com.icongyou.enterprise.talent_analysis.mapper.PortraitTemplateMapper;
import com.icongyou.enterprise.talent_analysis.mapper.HrTemplatePreferenceMapper;
import com.icongyou.enterprise.talent_analysis.service.PortraitTemplateService;
import com.icongyou.enterprise.talent_analysis.service.PortraitAsyncService;
import com.icongyou.enterprise.talent_analysis.service.support.TemplateDimensionAutoFiller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class PortraitTemplateServiceImpl implements PortraitTemplateService {

    private final PortraitTemplateMapper portraitTemplateMapper;
    private final HrTemplatePreferenceMapper preferenceMapper;
    private final TemplateDimensionAutoFiller dimensionAutoFiller;
    private final ObjectMapper objectMapper;
    private final PortraitAsyncService portraitAsyncService;

    private static final TypeReference<List<TemplateDimension>> DIMENSION_TYPE = new TypeReference<List<TemplateDimension>>() {};

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PortraitTemplateDTO createTemplate(PortraitTemplateCreateRequest request) {
        // 检查HR用户已创建的模板数量（最多2个）
        int existingCount = portraitTemplateMapper.countByCreatedBy(request.getCreatedBy());
        if (existingCount >= 2) {
            throw new BusinessException("每个HR用户最多只能创建2个模板，您已达到上限。请修改现有模板或删除后再创建。");
        }
        
        List<TemplateDimension> dimensions = request.getDimensions();
        if (CollectionUtils.isEmpty(dimensions)) {
            throw new BusinessException("模板必须包含六个维度");
        }
        if (dimensions.size() != 6) {
            throw new BusinessException("模板必须包含 6 个维度");
        }
        
        // 尝试自动填充预设指标（仅当维度代码匹配预设时）
        dimensionAutoFiller.fillMissingMetrics(dimensions);
        
        // 检查是否有维度仍然缺少指标
        boolean hasEmptyMetrics = dimensions.stream()
                .anyMatch(dim -> CollectionUtils.isEmpty(dim.getMetrics()));
        
        if (hasEmptyMetrics) {
            // 如果某些维度仍然缺少指标，视为无法自动补全，抛出业务异常
            throw new BusinessException("模板指标缺失，无法自动补全，请补充指标或选择预设模板");
        }
        
        String dimensionsJson = toJson(dimensions);

        PortraitTemplate entity = new PortraitTemplate();
        entity.setId(UUID.randomUUID().toString());
        entity.setEnterpriseId(request.getEnterpriseId());
        entity.setTemplateName(request.getTemplateName());
        entity.setDescription(request.getDescription());
        entity.setDimensionsJson(dimensionsJson);
        entity.setActive(Boolean.TRUE.equals(request.getActive()));
        entity.setAiSuggested(Boolean.TRUE.equals(request.getAiSuggested()));
        entity.setCreatedBy(request.getCreatedBy());
        entity.setCreatedAt(LocalDateTime.now());
        entity.setUpdatedAt(LocalDateTime.now());

        if (Boolean.TRUE.equals(request.getActive())) {
            portraitTemplateMapper.clearActiveFlag(request.getEnterpriseId());
        }
        portraitTemplateMapper.insert(entity);
        
        // 新模板创建并激活时，触发所有学生画像批量更新
        if (Boolean.TRUE.equals(request.getActive())) {
            portraitAsyncService.triggerBatchUpdate(entity.getId(), "TEMPLATE_CREATED");
        }
        
        return toDto(entity, dimensions);
    }

    @Override
    public PortraitTemplateDTO getTemplate(String templateId) {
        PortraitTemplate entity = portraitTemplateMapper.selectById(templateId);
        if (entity == null) {
            throw new BusinessException(404, "模板不存在");
        }
        return toDto(entity, fromJson(entity.getDimensionsJson()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PortraitTemplateDTO updateTemplate(String templateId, PortraitTemplateDTO template) {
        // 检查模板是否存在
        PortraitTemplate existingTemplate = portraitTemplateMapper.selectById(templateId);
        if (existingTemplate == null) {
            throw new BusinessException(404, "模板不存在");
        }
        
        // 验证维度数量
        List<TemplateDimension> dimensions = template.getDimensions();
        if (CollectionUtils.isEmpty(dimensions)) {
            throw new BusinessException("模板必须包含六个维度");
        }
        if (dimensions.size() != 6) {
            throw new BusinessException("模板必须包含 6 个维度");
        }
        
        // 序列化维度数据
        String dimensionsJson = toJson(dimensions);
        
        // 更新模板信息
        existingTemplate.setTemplateName(template.getTemplateName());
        existingTemplate.setDescription(template.getDescription());
        existingTemplate.setDimensionsJson(dimensionsJson);
        existingTemplate.setUpdatedAt(LocalDateTime.now());
        
        // 如果激活状态有变化
        if (Boolean.TRUE.equals(template.getActive()) && !Boolean.TRUE.equals(existingTemplate.getActive())) {
            // 新激活的模板，需要清除其他模板的激活状态
            portraitTemplateMapper.clearActiveFlag(existingTemplate.getEnterpriseId());
            existingTemplate.setActive(true);
            
            // 触发画像批量更新
            portraitAsyncService.triggerBatchUpdate(templateId, "TEMPLATE_UPDATED");
        } else {
            existingTemplate.setActive(Boolean.TRUE.equals(template.getActive()));
        }
        
        // 更新数据库
        portraitTemplateMapper.updateById(existingTemplate);
        
        return toDto(existingTemplate, dimensions);
    }

    @Override
    public List<PortraitTemplateDTO> listTemplates(String enterpriseId, Boolean active) {
        try {
            List<PortraitTemplate> templates = portraitTemplateMapper.selectByEnterprise(enterpriseId, active);
            
            if (templates == null || templates.isEmpty()) {
                return new ArrayList<>();
            }
            
            return templates.stream()
                    .map(t -> {
                        try {
                            return toDto(t, fromJson(t.getDimensionsJson()));
                        } catch (Exception e) {
                            log.error("转换模板失败 - 模板ID: {}, 模板名称: {}, JSON内容: {}", 
                                t.getId(), t.getTemplateName(), t.getDimensionsJson(), e);
                            throw new BusinessException("转换模板失败: " + e.getMessage());
                        }
                    })
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询模板列表异常", e);
            throw new BusinessException("查询模板列表失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTemplate(String templateId) {
        PortraitTemplate template = portraitTemplateMapper.selectById(templateId);
        if (template == null) {
            throw new BusinessException(404, "模板不存在");
        }
        
        // 1. 先清除HR用户对该模板的偏好引用
        preferenceMapper.clearTemplateReference(templateId);
        
        // 2. 清理使用该模板的画像缓存（同步执行，确保在事务内）
        portraitAsyncService.clearCacheByTemplate(templateId);
        
        // 3. 最后删除模板
        portraitTemplateMapper.deleteById(templateId);
    }

    private String toJson(List<TemplateDimension> dimensions) {
        try {
            return objectMapper.writeValueAsString(dimensions);
        } catch (JsonProcessingException e) {
            throw new BusinessException("模板维度序列化失败");
        }
    }

    private List<TemplateDimension> fromJson(String json) {
        try {
            if (json == null || json.trim().isEmpty()) {
                return new ArrayList<>();
            }
            
            // 尝试解析为Map结构 {"维度名称": {...}}
            if (json.trim().startsWith("{")) {
                com.fasterxml.jackson.core.type.TypeReference<java.util.Map<String, java.util.Map<String, Object>>> mapType = 
                    new com.fasterxml.jackson.core.type.TypeReference<java.util.Map<String, java.util.Map<String, Object>>>() {};
                java.util.Map<String, java.util.Map<String, Object>> dimensionMap = objectMapper.readValue(json, mapType);
                
                List<TemplateDimension> dimensions = new ArrayList<>();
                for (java.util.Map.Entry<String, java.util.Map<String, Object>> entry : dimensionMap.entrySet()) {
                    TemplateDimension dimension = new TemplateDimension();
                    dimension.setName(entry.getKey());
                    dimension.setCode(entry.getKey()); // 暂时使用名称作为code
                    
                    java.util.Map<String, Object> dimData = entry.getValue();
                    if (dimData.containsKey("weight")) {
                        dimension.setWeight(((Number) dimData.get("weight")).doubleValue());
                    }
                    
                    // 解析indicators为metrics
                    if (dimData.containsKey("indicators")) {
                        @SuppressWarnings("unchecked")
                        List<java.util.Map<String, Object>> indicators = (List<java.util.Map<String, Object>>) dimData.get("indicators");
                        List<TemplateMetricMapping> metrics = new ArrayList<>();
                        for (java.util.Map<String, Object> indicator : indicators) {
                            TemplateMetricMapping metric = new TemplateMetricMapping();
                            metric.setMetricKey((String) indicator.get("name"));
                            if (indicator.containsKey("weight")) {
                                metric.setWeight(((Number) indicator.get("weight")).doubleValue());
                            }
                            metrics.add(metric);
                        }
                        dimension.setMetrics(metrics);
                    }
                    
                    dimensions.add(dimension);
                }
                return dimensions;
            }
            
            // 如果是数组格式,直接解析
            return objectMapper.readValue(json, DIMENSION_TYPE);
        } catch (Exception e) {
            log.error("模板维度反序列化失败,JSON内容: {}", json, e);
            throw new BusinessException("模板维度反序列化失败: " + e.getMessage());
        }
    }

    private PortraitTemplateDTO toDto(PortraitTemplate entity, List<TemplateDimension> dimensions) {
        PortraitTemplateDTO dto = new PortraitTemplateDTO();
        dto.setId(entity.getId());
        dto.setEnterpriseId(entity.getEnterpriseId());
        dto.setTemplateName(entity.getTemplateName());
        dto.setDescription(entity.getDescription());
        dto.setActive(Boolean.TRUE.equals(entity.getActive()));
        dto.setAiSuggested(Boolean.TRUE.equals(entity.getAiSuggested()));
        dto.setCreatedBy(entity.getCreatedBy());
        dto.setCreatedAt(entity.getCreatedAt());
        dto.setUpdatedAt(entity.getUpdatedAt());
        dto.setDimensions(dimensions);
        return dto;
    }
}
